﻿using System;
using FortuneUniverse.Fortune.Algorithms;

namespace FortuneUniverse.Fortune.Dyson
{
  public static class Maths
  {
    public static double Clamp01(double val)
    {
      if (val < 0.0)
        return 0.0;
      return val > 1.0 ? 1.0 : val;
    }

    public static double Clamp(double val, double min, double max)
    {
      if (val < min)
        return min;
      return val > max ? max : val;
    }

    public static Vector3 Forward(this Quaternion rotation)
    {
      float num1 = rotation.x * 2f;
      float num2 = rotation.y * 2f;
      float num3 = rotation.z * 2f;
      float num4 = rotation.x * num1;
      float num5 = rotation.y * num2;
      double num6 = (double) rotation.x * (double) num3;
      float num7 = rotation.y * num3;
      float num8 = rotation.w * num1;
      double num9 = (double) (rotation.w * num2);
      return new Vector3((float) (num6 + num9), num7 - num8, (float) (1.0 - ((double) num4 + (double) num5)));
    }

    public static Vector3 Up(this Quaternion rotation)
    {
      float num1 = rotation.x * 2f;
      float num2 = rotation.y * 2f;
      float num3 = rotation.z * 2f;
      float num4 = rotation.x * num1;
      float num5 = rotation.z * num3;
      double num6 = (double) rotation.x * (double) num2;
      float num7 = rotation.y * num3;
      float num8 = rotation.w * num1;
      double num9 = (double) (rotation.w * num3);
      return new Vector3((float) (num6 - num9), (float) (1.0 - ((double) num4 + (double) num5)), num7 + num8);
    }

    public static void ForwardUp(this Quaternion rotation, out Vector3 fwd, out Vector3 up)
    {
      float num1 = rotation.x * 2f;
      float num2 = rotation.y * 2f;
      float num3 = rotation.z * 2f;
      float num4 = rotation.x * num1;
      float num5 = rotation.y * num2;
      float num6 = rotation.z * num3;
      float num7 = rotation.x * num2;
      float num8 = rotation.x * num3;
      float num9 = rotation.y * num3;
      float num10 = rotation.w * num1;
      float num11 = rotation.w * num2;
      float num12 = rotation.w * num3;
      fwd = new Vector3(num8 + num11, num9 - num10, (float) (1.0 - ((double) num4 + (double) num5)));
      up = new Vector3(num7 - num12, (float) (1.0 - ((double) num4 + (double) num6)), num9 + num10);
    }

    public static Vector3 Right(this Quaternion rotation)
    {
      float num1 = rotation.y * 2f;
      float num2 = rotation.z * 2f;
      float num3 = rotation.y * num1;
      float num4 = rotation.z * num2;
      float num5 = rotation.x * num1;
      float num6 = rotation.x * num2;
      float num7 = rotation.w * num1;
      float num8 = rotation.w * num2;
      return new Vector3((float) (1.0 - ((double) num3 + (double) num4)), num5 + num8, num6 - num7);
    }

    public static Vector3 Back(this Quaternion rotation)
    {
      float num1 = rotation.x * 2f;
      float num2 = rotation.y * 2f;
      float num3 = rotation.z * 2f;
      float num4 = rotation.x * num1;
      float num5 = rotation.y * num2;
      double num6 = (double) rotation.x * (double) num3;
      float num7 = rotation.y * num3;
      float num8 = rotation.w * num1;
      float num9 = rotation.w * num2;
      return new Vector3((float) -num6 - num9, num8 - num7, (float) ((double) num4 + (double) num5 - 1.0));
    }

    public static Vector3 Down(this Quaternion rotation)
    {
      float num1 = rotation.x * 2f;
      float num2 = rotation.y * 2f;
      float num3 = rotation.z * 2f;
      float num4 = rotation.x * num1;
      float num5 = rotation.z * num3;
      float num6 = rotation.x * num2;
      float num7 = rotation.y * num3;
      float num8 = rotation.w * num1;
      return new Vector3(rotation.w * num3 - num6, (float) ((double) num4 + (double) num5 - 1.0), -num7 - num8);
    }

    public static Vector3 Left(this Quaternion rotation)
    {
      float num1 = rotation.y * 2f;
      float num2 = rotation.z * 2f;
      double num3 = (double) rotation.y * (double) num1;
      float num4 = rotation.z * num2;
      float num5 = rotation.x * num1;
      float num6 = rotation.x * num2;
      float num7 = rotation.w * num1;
      float num8 = rotation.w * num2;
      double num9 = (double) num4;
      return new Vector3((float) (num3 + num9 - 1.0), -num5 - num8, num7 - num6);
    }

    public static void EulerTo3Axis(
      this Vector3 euler,
      out Vector3 right,
      out Vector3 up,
      out Vector3 forward)
    {
      float num1 = Mathf.Sin(euler.x * ((float) Math.PI / 180f));
      float num2 = Mathf.Cos(euler.x * ((float) Math.PI / 180f));
      float num3 = Mathf.Sin(euler.y * ((float) Math.PI / 180f));
      float num4 = Mathf.Cos(euler.y * ((float) Math.PI / 180f));
      float num5 = Mathf.Sin(euler.z * ((float) Math.PI / 180f));
      float num6 = Mathf.Cos(euler.z * ((float) Math.PI / 180f));
      right = new Vector3((float) ((double) num6 * (double) num4 + (double) num5 * (double) num1 * (double) num3), num2 * num5, (float) ((double) num4 * (double) num5 * (double) num1 - (double) num6 * (double) num3));
      up = new Vector3((float) ((double) num6 * (double) num1 * (double) num3 - (double) num4 * (double) num5), num6 * num2, (float) ((double) num5 * (double) num3 + (double) num6 * (double) num4 * (double) num1));
      forward = new Vector3(num3 * num2, -num1, num4 * num2);
    }

    public static Vector3 StandardEuler(this Vector3 euler)
    {
      euler.x = Mathf.Repeat(euler.x + 180f, 360f) - 180f;
      if ((double) euler.x < -90.0)
      {
        euler.x = -180f - euler.x;
        euler.y += 180f;
      }
      else if ((double) euler.x > 90.0)
      {
        euler.x = 180f - euler.x;
        euler.y += 180f;
      }
      euler.y = Mathf.Repeat(euler.y + 180f, 360f) - 180f;
      euler.z = Mathf.Repeat(euler.z + 180f, 360f) - 180f;
      return euler;
    }

    public static Vector3 EulerForward(this Vector3 euler)
    {
      float num1 = Mathf.Sin(euler.x * ((float) Math.PI / 180f));
      float num2 = Mathf.Cos(euler.x * ((float) Math.PI / 180f));
      double num3 = (double) Mathf.Sin(euler.y * ((float) Math.PI / 180f));
      float num4 = Mathf.Cos(euler.y * ((float) Math.PI / 180f));
      double num5 = (double) num2;
      return new Vector3((float) (num3 * num5), -num1, num4 * num2);
    }

    public static Vector3 EulerUp(this Vector3 euler)
    {
      float num1 = Mathf.Sin(euler.x * ((float) Math.PI / 180f));
      float num2 = Mathf.Cos(euler.x * ((float) Math.PI / 180f));
      float num3 = Mathf.Sin(euler.y * ((float) Math.PI / 180f));
      float num4 = Mathf.Cos(euler.y * ((float) Math.PI / 180f));
      float num5 = Mathf.Sin(euler.z * ((float) Math.PI / 180f));
      float num6 = Mathf.Cos(euler.z * ((float) Math.PI / 180f));
      return new Vector3((float) ((double) num6 * (double) num1 * (double) num3 - (double) num4 * (double) num5), num6 * num2, (float) ((double) num5 * (double) num3 + (double) num6 * (double) num4 * (double) num1));
    }

    public static Vector3 EulerRight(this Vector3 euler)
    {
      float num1 = Mathf.Sin(euler.x * ((float) Math.PI / 180f));
      float num2 = Mathf.Cos(euler.x * ((float) Math.PI / 180f));
      float num3 = Mathf.Sin(euler.y * ((float) Math.PI / 180f));
      float num4 = Mathf.Cos(euler.y * ((float) Math.PI / 180f));
      float num5 = Mathf.Sin(euler.z * ((float) Math.PI / 180f));
      float num6 = Mathf.Cos(euler.z * ((float) Math.PI / 180f));
      return new Vector3((float) ((double) num6 * (double) num4 + (double) num5 * (double) num1 * (double) num3), num2 * num5, (float) ((double) num4 * (double) num5 * (double) num1 - (double) num6 * (double) num3));
    }

    public static Vector3 EulerBack(this Vector3 euler)
    {
      float y = Mathf.Sin(euler.x * ((float) Math.PI / 180f));
      float num1 = Mathf.Cos(euler.x * ((float) Math.PI / 180f));
      double num2 = (double) Mathf.Sin(euler.y * ((float) Math.PI / 180f));
      float num3 = Mathf.Cos(euler.y * ((float) Math.PI / 180f));
      return new Vector3((float) -num2 * num1, y, -num3 * num1);
    }

    public static Vector3 EulerDown(this Vector3 euler)
    {
      float num1 = Mathf.Sin(euler.x * ((float) Math.PI / 180f));
      float num2 = Mathf.Cos(euler.x * ((float) Math.PI / 180f));
      float num3 = Mathf.Sin(euler.y * ((float) Math.PI / 180f));
      float num4 = Mathf.Cos(euler.y * ((float) Math.PI / 180f));
      float num5 = Mathf.Sin(euler.z * ((float) Math.PI / 180f));
      float num6 = Mathf.Cos(euler.z * ((float) Math.PI / 180f));
      return new Vector3((float) ((double) num4 * (double) num5 - (double) num6 * (double) num1 * (double) num3), -num6 * num2, (float) (-(double) num5 * (double) num3 - (double) num6 * (double) num4 * (double) num1));
    }

    public static Vector3 EulerLeft(this Vector3 euler)
    {
      float num1 = Mathf.Sin(euler.x * ((float) Math.PI / 180f));
      float num2 = Mathf.Cos(euler.x * ((float) Math.PI / 180f));
      float num3 = Mathf.Sin(euler.y * ((float) Math.PI / 180f));
      float num4 = Mathf.Cos(euler.y * ((float) Math.PI / 180f));
      float num5 = Mathf.Sin(euler.z * ((float) Math.PI / 180f));
      float num6 = Mathf.Cos(euler.z * ((float) Math.PI / 180f));
      return new Vector3((float) (-(double) num6 * (double) num4 - (double) num5 * (double) num1 * (double) num3), -num2 * num5, (float) ((double) num6 * (double) num3 - (double) num4 * (double) num5 * (double) num1));
    }

    public static Vector3 HorzVector(Vector3 v, Vector3 n)
    {
      float num = (float) ((double) v.x * (double) n.x + (double) v.y * (double) n.y + (double) v.z * (double) n.z);
      return new Vector3(v.x - n.x * num, v.y - n.y * num, v.z - n.z * num);
    }

    public static void HorzVertVector(Vector3 v, Vector3 n, out Vector3 horz, out Vector3 vert)
    {
      float num = (float) ((double) v.x * (double) n.x + (double) v.y * (double) n.y + (double) v.z * (double) n.z);
      vert = new Vector3(n.x * num, n.y * num, n.z * num);
      horz = new Vector3(v.x - vert.x, v.y - vert.y, v.z - vert.z);
    }

    public static VectorLF3 HorzVector(VectorLF3 v, VectorLF3 n)
    {
      double num = v.x * n.x + v.y * n.y + v.z * n.z;
      return new VectorLF3(v.x - n.x * num, v.y - n.y * num, v.z - n.z * num);
    }

    public static void HorzVertVector(
      VectorLF3 v,
      VectorLF3 n,
      out VectorLF3 horz,
      out VectorLF3 vert)
    {
      double num = v.x * n.x + v.y * n.y + v.z * n.z;
      vert = new VectorLF3(n.x * num, n.y * num, n.z * num);
      horz = new VectorLF3(v.x - vert.x, v.y - vert.y, v.z - vert.z);
    }

    public static Vector3 QRotate(Quaternion q, Vector3 v)
    {
      float num1 = 2f * v.x;
      float num2 = 2f * v.y;
      float num3 = 2f * v.z;
      float num4 = (float) ((double) q.w * (double) q.w - 0.5);
      float num5 = (float) ((double) q.x * (double) num1 + (double) q.y * (double) num2 + (double) q.z * (double) num3);
      return new Vector3((float) ((double) num1 * (double) num4 + ((double) q.y * (double) num3 - (double) q.z * (double) num2) * (double) q.w + (double) q.x * (double) num5), (float) ((double) num2 * (double) num4 + ((double) q.z * (double) num1 - (double) q.x * (double) num3) * (double) q.w + (double) q.y * (double) num5), (float) ((double) num3 * (double) num4 + ((double) q.x * (double) num2 - (double) q.y * (double) num1) * (double) q.w + (double) q.z * (double) num5));
    }

    public static Vector3 QInvRotate(Quaternion q, Vector3 v)
    {
      float num1 = 2f * v.x;
      float num2 = 2f * v.y;
      float num3 = 2f * v.z;
      float num4 = (float) ((double) q.w * (double) q.w - 0.5);
      float num5 = (float) ((double) q.x * (double) num1 + (double) q.y * (double) num2 + (double) q.z * (double) num3);
      return new Vector3((float) ((double) num1 * (double) num4 - ((double) q.y * (double) num3 - (double) q.z * (double) num2) * (double) q.w + (double) q.x * (double) num5), (float) ((double) num2 * (double) num4 - ((double) q.z * (double) num1 - (double) q.x * (double) num3) * (double) q.w + (double) q.y * (double) num5), (float) ((double) num3 * (double) num4 - ((double) q.x * (double) num2 - (double) q.y * (double) num1) * (double) q.w + (double) q.z * (double) num5));
    }

    public static VectorLF3 QRotateLF(Quaternion q, VectorLF3 v)
    {
      double num1 = 2.0 * v.x;
      double num2 = 2.0 * v.y;
      double num3 = 2.0 * v.z;
      double num4 = (double) q.w * (double) q.w - 0.5;
      double num5 = (double) q.x * num1 + (double) q.y * num2 + (double) q.z * num3;
      return new VectorLF3(num1 * num4 + ((double) q.y * num3 - (double) q.z * num2) * (double) q.w + (double) q.x * num5, num2 * num4 + ((double) q.z * num1 - (double) q.x * num3) * (double) q.w + (double) q.y * num5, num3 * num4 + ((double) q.x * num2 - (double) q.y * num1) * (double) q.w + (double) q.z * num5);
    }

    public static VectorLF3 RotateLF(
      double axisx,
      double axisy,
      double axisz,
      double halfRad,
      VectorLF3 v)
    {
      double num1 = Math.Sin(halfRad);
      double num2 = axisx * num1;
      double num3 = axisy * num1;
      double num4 = axisz * num1;
      double num5 = Math.Cos(halfRad);
      double num6 = 2.0 * v.x;
      double num7 = 2.0 * v.y;
      double num8 = 2.0 * v.z;
      double num9 = num5 * num5 - 0.5;
      double num10 = num2 * num6 + num3 * num7 + num4 * num8;
      return new VectorLF3(num6 * num9 + (num3 * num8 - num4 * num7) * num5 + num2 * num10, num7 * num9 + (num4 * num6 - num2 * num8) * num5 + num3 * num10, num8 * num9 + (num2 * num7 - num3 * num6) * num5 + num4 * num10);
    }

    public static VectorLF3 QInvRotateLF(Quaternion q, VectorLF3 v)
    {
      double num1 = 2.0 * v.x;
      double num2 = 2.0 * v.y;
      double num3 = 2.0 * v.z;
      double num4 = (double) q.w * (double) q.w - 0.5;
      double num5 = (double) q.x * num1 + (double) q.y * num2 + (double) q.z * num3;
      return new VectorLF3(num1 * num4 - ((double) q.y * num3 - (double) q.z * num2) * (double) q.w + (double) q.x * num5, num2 * num4 - ((double) q.z * num1 - (double) q.x * num3) * (double) q.w + (double) q.y * num5, num3 * num4 - ((double) q.x * num2 - (double) q.y * num1) * (double) q.w + (double) q.z * num5);
    }

    public static float SphericalAngleAOBInRAD(Vector3 O, Vector3 A, Vector3 B)
    {
      double num1 = Math.Sqrt((double) O.x * (double) O.x + (double) O.y * (double) O.y + (double) O.z * (double) O.z);
      if (num1 < 9.99999974737875E-05)
        return 0.0f;
      Vector3 vector3_1;
      vector3_1.x = O.x / (float) num1;
      vector3_1.y = O.y / (float) num1;
      vector3_1.z = O.z / (float) num1;
      Vector3 vector3_2;
      vector3_2.x = A.x - O.x;
      vector3_2.y = A.y - O.y;
      vector3_2.z = A.z - O.z;
      Vector3 vector3_3;
      vector3_3.x = B.x - O.x;
      vector3_3.y = B.y - O.y;
      vector3_3.z = B.z - O.z;
      float num2 = (float) ((double) vector3_2.x * (double) vector3_1.x + (double) vector3_2.y * (double) vector3_1.y + (double) vector3_2.z * (double) vector3_1.z);
      float num3 = (float) ((double) vector3_3.x * (double) vector3_1.x + (double) vector3_3.y * (double) vector3_1.y + (double) vector3_3.z * (double) vector3_1.z);
      vector3_2.x -= num2 * vector3_1.x;
      vector3_2.y -= num2 * vector3_1.y;
      vector3_2.z -= num2 * vector3_1.z;
      vector3_3.x -= num3 * vector3_1.x;
      vector3_3.y -= num3 * vector3_1.y;
      vector3_3.z -= num3 * vector3_1.z;
      double num4 = (double) vector3_2.x * (double) vector3_3.x + (double) vector3_2.y * (double) vector3_3.y + (double) vector3_2.z * (double) vector3_3.z;
      double d1 = (double) vector3_2.x * (double) vector3_2.x + (double) vector3_2.y * (double) vector3_2.y + (double) vector3_2.z * (double) vector3_2.z;
      double d2 = (double) vector3_3.x * (double) vector3_3.x + (double) vector3_3.y * (double) vector3_3.y + (double) vector3_3.z * (double) vector3_3.z;
      double num5 = Math.Sqrt(d1) * Math.Sqrt(d2);
      return (float) Math.Acos(num4 / num5);
    }

    public static float SphericalSlopeRatio(Vector3 start, Vector3 end)
    {
      float magnitude1 = start.magnitude;
      float magnitude2 = end.magnitude;
      if ((double) magnitude1 == 0.0 && (double) magnitude2 == 0.0)
        return 0.0f;
      if ((double) magnitude1 == 0.0)
        return float.PositiveInfinity;
      if ((double) magnitude2 == 0.0)
        return float.NegativeInfinity;
      float magnitude3 = (end * (magnitude1 / magnitude2) - start).magnitude;
      if ((double) magnitude3 != 0.0)
        return (magnitude2 - magnitude1) / magnitude3;
      if ((double) magnitude1 == (double) magnitude2)
        return 0.0f;
      return (double) magnitude1 > (double) magnitude2 ? float.NegativeInfinity : float.PositiveInfinity;
    }

    public static void GetLatitudeLongitude(
      Vector3 pos,
      out int latd,
      out int latf,
      out int logd,
      out int logf,
      out bool north,
      out bool south,
      out bool west,
      out bool east)
    {
      pos = pos.normalized;
      float f = Mathf.Asin(pos.y);
      float num1 = 0.000145f;
      north = (double) pos.y > (double) num1;
      south = (double) pos.y < -(double) num1;
      float num2 = 0.0f;
      if ((double) Mathf.Abs(pos.x) > 0.000119999996968545 || (double) Mathf.Abs(pos.z) > 0.000119999996968545)
      {
        num2 = Mathf.Atan2(pos.x, -pos.z);
        east = (double) pos.x > (double) num1 * (double) Mathf.Cos(f);
        west = (double) pos.x < -(double) num1 * (double) Mathf.Cos(f);
      }
      else
      {
        east = false;
        west = false;
      }
      int num3 = Mathf.RoundToInt(Mathf.Abs((float) ((double) num2 * 57.2957801818848 * 60.0)));
      int num4 = Mathf.RoundToInt(Mathf.Abs((float) ((double) f * 57.2957801818848 * 60.0)));
      logd = num3 / 60;
      latd = num4 / 60;
      logf = num3 % 60;
      latf = num4 % 60;
    }

    public static void GetLatitudeLongitudeSpace(
      VectorLF3 pos,
      out int latd,
      out int latf,
      out int logd,
      out int logf,
      out double alt,
      out bool north,
      out bool south)
    {
      double magnitude = pos.magnitude;
      alt = magnitude;
      if (magnitude < 1.0)
      {
        latd = 0;
        latf = 0;
        logd = 0;
        logf = 0;
        north = false;
        south = false;
      }
      else
      {
        pos /= magnitude;
        double num1 = Math.Asin(pos.y);
        float num2 = 0.000145f;
        north = pos.y > (double) num2;
        south = pos.y < -(double) num2;
        double num3;
        if (Math.Abs(pos.x) > 0.000119999996968545 || Math.Abs(pos.z) > 0.000119999996968545)
        {
          num3 = Math.Atan2(pos.x, pos.z);
          if (num3 < 0.0)
            num3 += 2.0 * Math.PI;
        }
        else
          num3 = 0.0;
        int num4 = (int) (Math.Abs(num3 * (180.0 / Math.PI) * 60.0) + 0.5);
        int num5 = (int) (Math.Abs(num1 * (180.0 / Math.PI) * 60.0) + 0.5);
        logd = num4 / 60;
        latd = num5 / 60;
        logf = num4 % 60;
        latf = num5 % 60;
      }
    }

    public static Vector3 Elerp(Vector3 a, Vector3 b, float t)
    {
      float num1 = 1f - t;
      float num2 = (float) Math.Sqrt((double) a.x * (double) a.x + (double) a.y * (double) a.y + (double) a.z * (double) a.z);
      float num3 = (float) Math.Sqrt((double) b.x * (double) b.x + (double) b.y * (double) b.y + (double) b.z * (double) b.z);
      if ((double) num2 < 9.99999997475243E-07 || (double) num3 < 9.99999997475243E-07)
        return new Vector3((float) ((double) a.x * (double) num1 + (double) b.x * (double) t), (float) ((double) a.y * (double) num1 + (double) b.y * (double) t), (float) ((double) a.z * (double) num1 + (double) b.z * (double) t));
      Vector3 vector3_1 = new Vector3(a.x / num2, a.y / num2, a.z / num2);
      Vector3 vector3_2 = new Vector3(b.x / num3, b.y / num3, b.z / num3);
      double num4 = Math.Asin((double) vector3_1.y);
      float num5 = (float) Math.Atan2((double) vector3_1.z, (double) vector3_1.x);
      float num6 = (float) Math.Asin((double) vector3_2.y);
      float num7 = (float) Math.Atan2((double) vector3_2.z, (double) vector3_2.x);
      if ((double) vector3_1.x < 9.99999997475243E-07 && (double) vector3_1.x > -9.99999997475243E-07 && (double) vector3_1.z < 9.99999997475243E-07 && (double) vector3_1.z > -9.99999997475243E-07)
        num5 = num7;
      if ((double) vector3_2.x < 9.99999997475243E-07 && (double) vector3_2.x > -9.99999997475243E-07 && (double) vector3_2.z < 9.99999997475243E-07 && (double) vector3_2.z > -9.99999997475243E-07)
        num7 = num5;
      double num8 = (double) num1;
      float num9 = (float) (num4 * num8 + (double) num6 * (double) t);
      float num10 = Mathf.Repeat(num7 - num5, 6.283185f);
      if ((double) num10 > 3.14159274101257)
        num10 -= 6.283185f;
      double num11 = (double) num5 + (double) num10 * (double) t;
      float num12 = (float) ((double) num2 * (double) num1 + (double) num3 * (double) t);
      float num13 = (float) Math.Cos(num11);
      float num14 = (float) Math.Cos((double) num9);
      float num15 = (float) Math.Sin(num11);
      float num16 = (float) Math.Sin((double) num9);
      return new Vector3(num12 * num13 * num14, num12 * num16, num12 * num15 * num14);
    }

    public static bool RayIntersectsTriangle(
      Vector3 org,
      Vector3 dir,
      Vector3 A,
      Vector3 B,
      Vector3 C)
    {
      Vector3 lhs = B - A;
      Vector3 rhs = C - A;
      Vector3 normalized = Vector3.Cross(lhs, rhs).normalized;
      float num1 = (float) ((double) normalized.x * (double) dir.x + (double) normalized.y * (double) dir.y + (double) normalized.z * (double) dir.z);
      if ((double) num1 < 9.99999974737875E-05 && (double) num1 > -9.99999974737875E-05)
        return false;
      Vector3 vector3_1 = org + dir * ((float) -((double) Vector3.Dot(normalized, org) + (double) Vector3.Dot(normalized, A)) / num1);
      float num2 = (float) ((double) lhs.x * (double) lhs.x + (double) lhs.y * (double) lhs.y + (double) lhs.z * (double) lhs.z);
      float num3 = (float) ((double) rhs.x * (double) rhs.x + (double) rhs.y * (double) rhs.y + (double) rhs.z * (double) rhs.z);
      float num4 = (float) ((double) lhs.x * (double) rhs.x + (double) lhs.y * (double) rhs.y + (double) lhs.z * (double) lhs.z);
      float num5 = (float) ((double) num2 * (double) num3 - (double) num4 * (double) num4);
      if ((double) num5 < 9.99999974737875E-05 && (double) num5 > -9.99999974737875E-05)
        return false;
      Vector3 vector3_2 = vector3_1 - A;
      float num6 = (float) ((double) vector3_2.x * (double) lhs.x + (double) vector3_2.y * (double) lhs.y + (double) vector3_2.z * (double) lhs.z);
      float num7 = (float) ((double) vector3_2.x * (double) rhs.x + (double) vector3_2.y * (double) rhs.y + (double) vector3_2.z * (double) rhs.z);
      float num8 = 1f / num5;
      float num9 = (float) ((double) num3 * (double) num6 - (double) num4 * (double) num7) * num8;
      float num10 = (float) (-(double) num4 * (double) num6 + (double) num2 * (double) num7) * num8;
      return (double) num9 >= 0.0 && (double) num10 >= 0.0 && (double) num9 + (double) num10 <= 1.0;
    }

    public static double Levelize(double f, double level = 1.0, double offset = 0.0)
    {
      f = f / level - offset;
      double num1 = Math.Floor(f);
      double num2 = f - num1;
      double num3 = (3.0 - num2 - num2) * num2 * num2;
      f = num1 + num3;
      f = (f + offset) * level;
      return f;
    }

    public static double Levelize2(double f, double level = 1.0, double offset = 0.0)
    {
      f = f / level - offset;
      double num1 = Math.Floor(f);
      double num2 = f - num1;
      double num3 = (3.0 - num2 - num2) * num2 * num2;
      double num4 = (3.0 - num3 - num3) * num3 * num3;
      f = num1 + num4;
      f = (f + offset) * level;
      return f;
    }

    public static double Levelize3(double f, double level = 1.0, double offset = 0.0)
    {
      f = f / level - offset;
      double num1 = Math.Floor(f);
      double num2 = f - num1;
      double num3 = (3.0 - num2 - num2) * num2 * num2;
      double num4 = (3.0 - num3 - num3) * num3 * num3;
      double num5 = (3.0 - num4 - num4) * num4 * num4;
      f = num1 + num5;
      f = (f + offset) * level;
      return f;
    }

    public static double Levelize4(double f, double level = 1.0, double offset = 0.0)
    {
      f = f / level - offset;
      double num1 = Math.Floor(f);
      double num2 = f - num1;
      double num3 = (3.0 - num2 - num2) * num2 * num2;
      double num4 = (3.0 - num3 - num3) * num3 * num3;
      double num5 = (3.0 - num4 - num4) * num4 * num4;
      double num6 = (3.0 - num5 - num5) * num5 * num5;
      f = num1 + num6;
      f = (f + offset) * level;
      return f;
    }

    public static double Random01(ref uint seed)
    {
      seed = (uint) ((ulong) (seed % 2147483646U + 1U) * 48271UL % (ulong) int.MaxValue) - 1U;
      return (double) seed / 2147483646.0;
    }
  }
}
